﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using Ionic.Zip;
using log4net;

namespace Bridge.Packager
{
    /// <summary>
    /// Main Program for Packager.
    /// </summary>
    public class Program
    {
        static void Main(string[] args)
        {
            string directory = string.Empty;
            string packageName = string.Empty;
            string loadDLL = string.Empty;
            string outputPackageDirectory = string.Empty;

            int currentArg = 0;
            while (currentArg < args.Length)
            {
                switch (args[currentArg])
                {
                    case "-d":
                        currentArg++;
                        while (currentArg < args.Length && !args[currentArg].StartsWith("-"))
                        {
                            directory += args[currentArg];
                            currentArg++;
                        }
                        directory = directory.Replace("\"", "");
                        break;
                    case "-p":
                        currentArg++;
                        while (currentArg < args.Length && !args[currentArg].StartsWith("-"))
                        {
                            packageName += args[currentArg];
                            currentArg++;
                        }
                        packageName = packageName.Replace("\"", "");
                        break;
                    case "-l":
                        currentArg++;
                        while (currentArg < args.Length && !args[currentArg].StartsWith("-"))
                        {
                            loadDLL += args[currentArg];
                            currentArg++;
                        }
                        loadDLL = loadDLL.Replace("\"", "");
                        break;
                    case "-o":
                        currentArg++;
                        while (currentArg < args.Length && !args[currentArg].StartsWith("-"))
                        {
                            outputPackageDirectory += args[currentArg];
                            currentArg++;
                        }
                        outputPackageDirectory = outputPackageDirectory.Replace("\"", "");
                        break;
                    default:
                        throw new InvalidOperationException(string.Format("Invalid switch {0}", args[currentArg]));
                }
            }
            ZipPackage(directory, packageName, loadDLL, outputPackageDirectory);
        }

        private static void ZipPackage(string directory, string packageName, string loadDLL, string outputPackageDirectory)
        {
            if (string.IsNullOrEmpty(directory)) throw new ArgumentException("directory cannot be empty (switch -d)", "directory");
            if (string.IsNullOrEmpty(packageName)) throw new ArgumentException("package cannot be empty (switch -p)", "packageName");
            if (string.IsNullOrEmpty(loadDLL)) throw new ArgumentException("loadDLL cannot be empty (switch -l)", "loadDLL");
            if (string.IsNullOrEmpty(outputPackageDirectory)) throw new ArgumentException("outputPackageDirectory cannot be empty (switch -o)", "outputPackageDirectory");
            if (!Directory.Exists(directory)) throw new ArgumentException("directory (-d) does not exist.", "directory");
            if (!File.Exists(Path.Combine(directory, loadDLL))) throw new ArgumentException("loadDLL (-l) does not exist.", "loadDLL");

            DirectoryInfo inputDirectoryInfo = new DirectoryInfo(directory);
            FileInfo outputXmlInfo = new FileInfo(Path.Combine(directory, "Package.xml"));
            if (outputXmlInfo.Exists)
            {
                outputXmlInfo.Delete();
            }
            if (!Directory.Exists(outputPackageDirectory))
            {
                Directory.CreateDirectory(outputPackageDirectory);
            }
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings()
            {
                CloseOutput = true,
                Encoding = new UTF8Encoding(false),
                Indent = true,
                IndentChars = "  ",
                NewLineChars = "\r\n",
                OmitXmlDeclaration = true
            };
            using (XmlWriter xmlWriter = XmlWriter.Create(outputXmlInfo.FullName, xmlWriterSettings))
            {
                xmlWriter.WriteStartElement("package");

                xmlWriter.WriteStartElement("name");
                xmlWriter.WriteValue(packageName);
                xmlWriter.WriteEndElement(); //name

                xmlWriter.WriteStartElement("loadDLL");
                xmlWriter.WriteValue(loadDLL);
                xmlWriter.WriteEndElement(); //loadDLL

                xmlWriter.WriteEndElement();
            }
            string packageOutputFileName = Path.Combine(outputPackageDirectory, string.Format("{0}.bpkg", packageName));
            if (File.Exists(packageOutputFileName))
            {
                File.Delete(packageOutputFileName);
            }
            using (ZipFile zipFile = new ZipFile())
            {
                foreach (FileInfo fileInfo in inputDirectoryInfo.GetFiles())
                {
                    zipFile.AddFile(fileInfo.FullName, "");
                }
                zipFile.Save(packageOutputFileName);
            }
            sLog.InfoFormat("package saved to {0}", packageOutputFileName);
        }

        private static ILog sLog = LogManager.GetLogger("Program");
    }
}
